package pers.cj.pdos.controller;


import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.metadata.Sheet;
import com.alibaba.excel.support.ExcelTypeEnum;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import pers.cj.pdos.controller.base.BaseController;
import pers.cj.pdos.controller.entity.ResponseData;
import pers.cj.pdos.controller.entity.ResponseEntity;
import pers.cj.pdos.controller.entity.ResponseList;
import pers.cj.pdos.entity.*;
import pers.cj.pdos.excel.ExcelHouseOut;
import pers.cj.pdos.service.*;
import pers.cj.pdos.task.CleanTempExcelTask;
import pers.cj.pdos.utils.*;
import pers.cj.pdos.vo.*;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.util.*;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author chenj
 * @since 2020-02-21
 */
@Controller
@RequestMapping("/house")
public class HouseOutController extends BaseController {
    @Autowired
    IHouseOutService houseOutService;
    @Autowired
    IHouseInService houseInService;
    @Autowired
    IGoodsStockService goodsStockService;
    @Autowired
    IInGoodsRefundService inGoodsRefundService;
    @Autowired
    ISaleService saleService;
    @Autowired
    IGoodsTransferService goodsTransferService;
    @Autowired
    IBorrowOutService borrowOutService;
    @Autowired
    IBorrowInBackService borrowInBackService;
    @Autowired
    IGoodsService goodsService;
    @Autowired
    IPacketService packetService;


    @RequiresPermissions("houseOut:query")
    @RequestMapping("/houseOutMain")
    public String houseInMain(){
        return "houseOut/houseOutMain";
    }

    @RequiresPermissions("houseOut:query")
    @RequestMapping("/houseOut")
    public String houseOut(){
        return "houseOut/houseOut";
    }


    @RequiresPermissions("houseOut:houseOut")
    @RequestMapping("/houseOutNew")
    public String houseOutNew(Model model, String houseWaitOutId){
        model.addAttribute("houseWaitOutId",houseWaitOutId);
        return "houseOut/houseOutNew";
    }


    @RequiresPermissions("houseOut:query")
    @RequestMapping("/houseOutDetail")
    public String houseOutDetail(Model model, String id){
        model.addAttribute("id",id);
        return "houseOut/houseOutDetail";
    }

    @ResponseBody
    @RequiresPermissions("houseOut:query")
    @RequestMapping("/houseOut/getList")
    public ResponseList getList(int page,
                                int limit,
                                String close,
                                String type,
                                String search,
                                String no,
                                String linkNo,
                                String goodsName,
                                String remark,
                                String unitName,
                                String makeTime1,
                                String makeTime2,
                                String makeUserId,
                                String userId,
                                String date1,
                                String date2,
                                String storeId,
                                String houseId){
        Company company = getCompany();
        UserVo userVo = getLoginUserVo();
        List<HouseOutVo> list = houseOutService.listVo(company.getId(),
                page,
                limit,
                Utils.genBoolean(close),
                Utils.genInteger(type),
                Utils.genLikeData(search),
                Utils.genLikeData(no),
                Utils.genLikeData(linkNo),
                Utils.genLikeData(goodsName),
                Utils.genLikeData(remark),
                Utils.genLikeData(unitName),
                Utils.genDate(makeTime1),
                Utils.genDate(makeTime2),
                makeUserId,
                PdosUtils.getViewOrderStoreId(userVo,null),
                PdosUtils.getViewOrderUserId(userVo,userId),
                Utils.genDate(date1),
                Utils.genDate(date2),
                storeId,
                houseId);

        long count = houseOutService.count(company.getId(),
                Utils.genBoolean(close),
                Utils.genInteger(type),
                Utils.genLikeData(search),
                Utils.genLikeData(no),
                Utils.genLikeData(linkNo),
                Utils.genLikeData(goodsName),
                Utils.genLikeData(remark),
                Utils.genLikeData(unitName),
                Utils.genDate(makeTime1),
                Utils.genDate(makeTime2),
                makeUserId,
                PdosUtils.getViewOrderStoreId(userVo,null),
                PdosUtils.getViewOrderUserId(userVo,userId),
                Utils.genDate(date1),
                Utils.genDate(date2),
                storeId,
                houseId);

        return ResponseList.success(count,list);
    }

    @ResponseBody
    @RequiresPermissions("houseOut:houseOut")
    @RequestMapping("/houseOut/add")
    public ResponseEntity add(@RequestBody HouseOutVo houseOutVo){
        Company company = getCompany();
        BusinessSet businessSet = getBusinessSet();

        if (Utils.isEmpty(houseOutVo.getNo())){
            return ResponseEntity.fail("编号不能为空");
        }

        if (Utils.isEmpty(houseOutVo.getHouseId())){
            return ResponseEntity.fail("houseId不能为空");
        }

        if (Utils.isEmpty(houseOutVo.getHouseOutGoodsVoList()) && Utils.isEmpty(houseOutVo.getHouseOutPacketVoList())){
            return ResponseEntity.fail("您未选择任何商品");
        }

        if (houseOutVo.getDate() == null){
            return ResponseEntity.fail("业务日期不能为空");
        }

        if (houseOutService.checkNo(houseOutVo.getNo(),company.getId())){
            return ResponseEntity.fail("编号已被使用");
        }

        if (houseOutService.checkNo(houseOutVo.getNo(),company.getId())){
            return ResponseEntity.fail("编号已被使用");
        }

        GoodsUtil goodsUtil = new GoodsUtil(houseOutVo.getHouseId(),houseOutVo.getHouseOutGoodsVoList(), houseOutVo.getHouseOutPacketVoList());
        if (!PdosUtils.negativeSale(businessSet) ||  houseOutVo.getType() != 2){
            //允许销售负库存未开启 或 不是销售，则需要检查库存
            String msg = goodsUtil.checkStock();
            if (msg!=null){
                return ResponseEntity.fail(msg);
            }
        }



        HouseOut houseOut = DataUtil.genEntityFromVo(HouseOut.class, houseOutVo);
        DataUtil.processEntity(company,houseOut);
        houseOut.setClose(false);//正常
        houseOut.setMakeUserId(getLoginUserId());
        houseOut.setMakeTime(new Date());

        List<HouseOutGoods> houseOutGoodsList= new ArrayList<>();
        List<GoodsSn> goodsSnList= new ArrayList<>();
        List<GoodsSnLog> goodsSnLogList= new ArrayList<>();

        if (!Utils.isEmpty(houseOutVo.getHouseOutGoodsVoList())) {
            for (HouseOutGoodsVo vo : houseOutVo.getHouseOutGoodsVoList()) {
                HouseOutGoods entity = DataUtil.genEntityFromVo(HouseOutGoods.class, vo);
                DataUtil.processEntity(company, entity);
                entity.setHouseOutId(houseOut.getId());
                houseOutGoodsList.add(entity);

                if (!Utils.isEmpty(vo.getGoodsSnList())) {
                    for (GoodsSn goodsSn : vo.getGoodsSnList()) {
                        goodsSnList.add(goodsSn);

                        GoodsSnLog log = new GoodsSnLog();
                        DataUtil.processEntity(company, log);
                        log.setGoodsId(goodsSn.getGoodsId());
                        log.setSn(goodsSn.getSn());
                        log.setType(6);
                        log.setHouseOutGoodsId(entity.getId());
                        goodsSnLogList.add(log);
                    }
                }
            }
        }

        List<HouseOutPacket> houseOutPacketList= new ArrayList<>();
        List<HouseOutPacketGoods> houseOutPacketGoodsList= new ArrayList<>();
        if (!Utils.isEmpty(houseOutVo.getHouseOutPacketVoList())) {
            for (HouseOutPacketVo vo : houseOutVo.getHouseOutPacketVoList()) {
                HouseOutPacket entity = DataUtil.genEntityFromVo(HouseOutPacket.class, vo);
                DataUtil.processEntity(company, entity);
                entity.setHouseOutId(houseOut.getId());
                houseOutPacketList.add(entity);


                for (HouseOutPacketGoodsVo pgv : vo.getPacketGoodsVoList()) {
                    HouseOutPacketGoods pg = DataUtil.genEntityFromVo(HouseOutPacketGoods.class, pgv);
                    DataUtil.processEntity(company, pg);
                    pg.setHouseOutId(entity.getHouseOutId());
                    pg.setHouseOutPacketId(entity.getId());
                    houseOutPacketGoodsList.add(pg);
                }
            }
        }




        houseOutService.insert(houseOut,houseOutGoodsList, goodsSnList,goodsSnLogList,houseOutPacketList,houseOutPacketGoodsList);
        return ResponseEntity.success();
    }


    @ResponseBody
    @RequiresPermissions("houseOut:close")
    @RequestMapping("/houseOut/close")
    public ResponseEntity close(@RequestBody HouseOut houseOut){
        HouseOut old = houseOutService.getById(houseOut.getId());

        //检查是否已经关闭
        if (old.getClose()){
            return ResponseEntity.fail("该单据已被关闭，不能重复关闭");
        }

        //调拨单需要先检查其有没有对应的未作废入库单
        if (old.getType() == 3 && houseInService.count(new QueryWrapper<HouseIn>().eq("house_out_id",old.getId()).eq("close",false))>0){
            return ResponseEntity.fail("关联单是调拨单，此出库单有对应的入库单，需要先作废");
        }

        houseOutService.close(houseOut);
        return ResponseEntity.success();
    }


    @ResponseBody
    @RequiresPermissions("houseOut:query")
    @RequestMapping("/houseOut/getVoById")
    public ResponseData getVoById(String id) {
        return ResponseData.success(houseOutService.getVoById(id));
    }



    @ResponseBody
    @RequiresPermissions("houseOut:query")
    @RequestMapping("/houseOut/listVoByHouseWaitOut")
    public ResponseData listVoByHouseWaitIn(String houseWaitOutId) {
        return ResponseData.success(houseOutService.listVoByHouseWaitOut(houseWaitOutId));
    }

    /**
     * 先更具请求数据
     * @throws IOException
     */
    @ResponseBody
    @RequiresPermissions("houseOut:export")
    @RequestMapping("/houseOut/export")
    public ResponseData export(String close,
                               String type,
                               String search,
                               String no,
                               String linkNo,
                               String goodsName,
                               String remark,
                               String unitName,
                               String makeTime1,
                               String makeTime2,
                               String makeUserId,
                               String userId,
                               String date1,
                               String date2,
                               String storeId,
                               String houseId){
        Company company = getCompany();
        UserVo userVo = getLoginUserVo();
        List<HouseOutVo> list = houseOutService.listVo(company.getId(),
                null,
                null,
                Utils.genBoolean(close),
                Utils.genInteger(type),
                Utils.genLikeData(search),
                Utils.genLikeData(no),
                Utils.genLikeData(linkNo),
                Utils.genLikeData(goodsName),
                Utils.genLikeData(remark),
                Utils.genLikeData(unitName),
                Utils.genDate(makeTime1),
                Utils.genDate(makeTime2),
                makeUserId,
                PdosUtils.getViewOrderStoreId(userVo,null),
                PdosUtils.getViewOrderUserId(userVo,userId),
                Utils.genDate(date1),
                Utils.genDate(date2),
                storeId,
                houseId);
        String fileName = "出库单列表" + DateUtils.getDate(new Date(), DateUtils.YYYYMMDDHHMMSSSS) + ".xlsx";
        try {
            String path = FileProperUtil.getInstance().getVal("excel.temp");
            OutputStream out = new FileOutputStream(path+fileName);
            ExcelWriter writer = new ExcelWriter(out, ExcelTypeEnum.XLSX,true);
            Sheet sheet1 = new Sheet(1,0, ExcelHouseOut.class);
            sheet1.setSheetName("出库单信息");
            writer.write(genExcelList(list), sheet1);
            writer.finish();
            out.close();
            CleanTempExcelTask.put(fileName,new Date().getTime());
            return ResponseData.success(fileName);
        } catch (IOException e) {
            return ResponseData.fail("订单列表导出失败");
        }
    }

    private List<ExcelHouseOut> genExcelList(List<HouseOutVo> houseOutVoList) {
        List<ExcelHouseOut> list = new ArrayList<>();
        for (HouseOutVo vo : houseOutVoList){
            ExcelHouseOut excel = new ExcelHouseOut();
            excel.setDate(DateUtils.getDate(vo.getDate(), DateUtils.YYYY_MM_DD));
            excel.setNo(vo.getNo());
            if (vo.getType() == 1){
                excel.setLinkNo(vo.getInGoodsRefundVo().getNo());
                excel.setUnit(vo.getInGoodsRefundVo().getProvider().getName());
                excel.setLinkBusiness("进货退货");
            } else if (vo.getType() == 2){
                excel.setLinkNo(vo.getSaleVo().getNo());
                excel.setUnit(vo.getSaleVo().getCustom().getName());
                excel.setLinkBusiness("销售");
            } else if (vo.getType() == 3){
                excel.setLinkNo(vo.getGoodsTransferVo().getNo());
                excel.setUnit("");
                excel.setLinkBusiness("调拨");
            } else if (vo.getType() == 4){
                excel.setLinkNo(vo.getBorrowOutVo().getNo());
                excel.setUnit(vo.getBorrowOutVo().getCustom().getName());
                excel.setLinkBusiness("借出");
            } else if (vo.getType() == 5){
                excel.setLinkNo(vo.getBorrowInBackVo().getNo());
                excel.setUnit(vo.getBorrowInBackVo().getProvider().getName());
                excel.setLinkBusiness("借入归还");
            }
            excel.setStore(vo.getHouseVo().getStore().getName());
            excel.setHouse(vo.getHouseVo().getName());

            String goods = "";
            BigDecimal number = new BigDecimal(0);
            for (HouseOutGoodsVo houseOutGoodsVo : vo.getHouseOutGoodsVoList()){
                number = number.add(houseOutGoodsVo.getNumber());
                goods += houseOutGoodsVo.getGoodsVo().getName() + "、";
            }
            for (HouseOutPacketVo houseOutPacketVo : vo.getHouseOutPacketVoList()){
                number = number.add(houseOutPacketVo.getNumber());
                goods += houseOutPacketVo.getPacketName() + "、";
            }

            goods = goods.substring(0,goods.length()-1);
            excel.setGoods(goods);

            excel.setNumber(PdosUtils.getNumber(number,getBusinessSet()));
            excel.setUser(vo.getUser().getName());
            excel.setMaker(vo.getMakeUser().getName());
            excel.setRemark(vo.getRemark());
            excel.setClose(vo.getClose() ? "是":"否");
            list.add(excel);
        }
        return list;
    }
}
